/*--------------------------------------------------
file name  : prj_scoreboard.sv
created    : 2025/08/16 18:14:35
description: 
notes      : 
author     : yyrwkk
--------------------------------------------------*/
`ifndef PRJ_SCOREBOARD_SV
`define PRJ_SCOREBOARD_SV
class prj_scoreboard #(type trans_t = uvm_sequence_item) extends uvm_scoreboard;

    uvm_tlm_analysis_fifo#(trans_t) exp_export;
    uvm_tlm_analysis_fifo#(trans_t) act_export;

    trans_t exp_tr;
    trans_t act_tr;

    trans_t exp_queue[$];

    `uvm_component_utils(prj_scoreboard)

    function new( string name = "prj_scorebaord", uvm_component parent = null);
        super.new(name, parent);
    endfunction 

    extern function void build_phase(uvm_phase phase);
    extern task main_phase(uvm_phase phase);
    extern function void compare_inorder( trans_t act_tr);

endclass

function void prj_scoreboard::build_phase(uvm_phase phase);
    super.build_phase( phase );
    exp_export = new("exp_export", this);
    act_export = new("act_export", this);
    `prj_medium("[build phase] done !")
endfunction

task prj_scoreboard::main_phase(uvm_phase phase);
    super.main_phase( phase );
    fork
        begin 
            exp_export.get(exp_tr);
            exp_queue.push_back(exp_tr);
        end
        begin 
            act_export.get(act_tr);
            compare_inorder(act_tr);
        end
    join 
    `prj_medium("[main phase] done !")
endtask

function void prj_scoreboard::compare_inorder( trans_t act_tr);
    trans_t exp_tr;
    if( exp_queue.size() == 0 ) `prj_error($sformatf("exp queue is empty!\nact tr is:\n%s",act_tr.sprint())) 
    else begin 
        exp_tr = exp_queue.pop_front();
        if( exp_tr.compare(act_tr) != 1 ) `prj_error($sformatf("exp_tr not equal act_tr!\nact_tr is: \n%s exp_tr is:\n%s",
                                                           act_tr.sprint, exp_tr.sprint)) 
        end
    end
endfunction 

`endif

